package com.bank.sdb.util.encryption;

import java.io.PrintStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * ��������ѹ����Ӧ����. 
 * 
 * ����CRYPT�㷨����ѹ���ͽ�ѹ. 
 */
public class PasswordHandler
{

    PasswordHandler()
    {
    }

    private static byte[] concatenate(byte[] abyte0, byte[] abyte1)
    {
        byte abyte2[] = new byte[abyte0.length + abyte1.length];
        System.arraycopy(abyte0, 0, abyte2, 0, abyte0.length);
        System.arraycopy(abyte1, 0, abyte2, abyte0.length, abyte1.length);
        return abyte2;
    }

    private static byte[] fromHex(String s)
    {
        s = s.toLowerCase();
        byte abyte0[] = new byte[(s.length() + 1) / 2];
        int i = 0;
        int j = -1;
        for(int k = 0; k < s.length(); k++)
        {
            int l = hexits.indexOf(s.charAt(k));
            if(l >= 0)
                if(j < 0)
                {
                    j = l;
                } else
                {
                    abyte0[i++] = (byte)((j << 4) + l);
                    j = -1;
                }
        }

        if(j >= 0)
            abyte0[i++] = (byte)(j << 4);
        if(i < abyte0.length)
        {
            byte abyte1[] = new byte[i];
            System.arraycopy(abyte0, 0, abyte1, 0, i);
            abyte0 = abyte1;
        }
        return abyte0;
    }

    public static String generateDigest(String s, String s1, String s2)
    {
        if(s2.equalsIgnoreCase("crypt"))
            return "{CRYPT}" + UnixCrypt.crypt(s);
        MessageDigest messagedigest = getAlgorithm(s2);
        if(messagedigest == null)
            return null;
        byte abyte0[] = new byte[0];
        if(s1 != null)
            abyte0 = fromHex(s1);
        String s3 = null;
        if(s2.startsWith("SHA"))
            s3 = abyte0.length > 0 ? "{SSHA}" : "{SHA}";
        else
        if(s2.startsWith("MD5"))
            s3 = abyte0.length > 0 ? "{SMD5}" : "{MD5}";
        messagedigest.reset();
        messagedigest.update(s.getBytes());
        messagedigest.update(abyte0);
        byte abyte1[] = messagedigest.digest();
        StringBuffer stringbuffer = new StringBuffer(s3);
        stringbuffer.append(Base64.encode(concatenate(abyte1, abyte0)));
        return stringbuffer.toString();
    }

    public static String generateDigest(String s)
    {
        return UnixCrypt.crypt(s);
    }

    private static MessageDigest getAlgorithm(String s)
    {
        try
        {
            return MessageDigest.getInstance(s);
        }
        catch(NoSuchAlgorithmException nosuchalgorithmexception)
        {
            System.out.println(s + " algorithm not available");
        }
        return null;
    }

    private static byte[][] split(byte[] abyte0, int i)
    {
        byte abyte1[];
        byte abyte2[];
        if(abyte0.length <= i)
        {
            abyte1 = abyte0;
            abyte2 = new byte[0];
        } else
        {
            abyte1 = new byte[i];
            abyte2 = new byte[abyte0.length - i];
            System.arraycopy(abyte0, 0, abyte1, 0, i);
            System.arraycopy(abyte0, i, abyte2, 0, abyte2.length);
        }
        byte abyte3[][] = {
            abyte1, abyte2
        };
        return abyte3;
    }

    private static String toHex(byte[] abyte0)
    {
        StringBuffer stringbuffer = new StringBuffer();
        for(int i = 0; i < abyte0.length; i++)
        {
            stringbuffer.append(hexits.charAt(abyte0[i] >>> 4 & 0xf));
            stringbuffer.append(hexits.charAt(abyte0[i] & 0xf));
        }

        return String.valueOf(String.valueOf(stringbuffer));
    }

    public static boolean verifyPassword(String s, String s1)
    {
        String s2 = null;
        byte byte0 = 0;
        if(s.regionMatches(true, 0, "{CRYPT}", 0, 7))
        {
            s = s.substring(7);
            return UnixCrypt.matches(s, s1);
        }
        if(s.regionMatches(true, 0, "{SHA}", 0, 5))
        {
            s = s.substring(5);
            s2 = "SHA-1";
            byte0 = 20;
        } else
        if(s.regionMatches(true, 0, "{SSHA}", 0, 6))
        {
            s = s.substring(6);
            s2 = "SHA-1";
            byte0 = 20;
        } else
        if(s.regionMatches(true, 0, "{MD5}", 0, 5))
        {
            s = s.substring(5);
            s2 = "MD5";
            byte0 = 14;
        } else
        if(s.regionMatches(true, 0, "{SMD5}", 0, 6))
        {
            s = s.substring(6);
            s2 = "MD5";
            byte0 = 16;
        }
        MessageDigest messagedigest = getAlgorithm(s2);
        if(messagedigest == null)
        {
            return false;
        } else
        {
            byte abyte0[][] = split(Base64.decode(s.toCharArray()), byte0);
            byte abyte1[] = abyte0[0];
            byte abyte2[] = abyte0[1];
            messagedigest.reset();
            messagedigest.update(s1.getBytes());
            messagedigest.update(abyte2);
            byte abyte3[] = messagedigest.digest();
            return MessageDigest.isEqual(abyte1, abyte3);
        }
    }

    public static boolean verifyPasswd(String s, String s1)
    {
        return UnixCrypt.matches(s, s1);
    }

    public static MessageDigest sha = null;
    private static String hexits = "0123456789abcdef";

    static
    {
        try
        {
            sha = MessageDigest.getInstance("SHA-1");
        }
        catch(NoSuchAlgorithmException nosuchalgorithmexception)
        {
            System.out.println("SHA algorithm not available");
        }
    }
}
